package com.alkin.thing.common.utils;

import com.alkin.thing.framework.web.domain.TreeSelect;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class TreeUtils {
    public static <T> List<TreeSelect> buildTreeSelect(List<T> list,
                                                       Function<T, Long> idFunc,
                                                       Function<T, String> labelFunc,
                                                       Function<T, Long> parentIdFunc
    ) {

        List<TreeSelect> all = list.stream().map(item -> {
            TreeSelect treeSelect = new TreeSelect();
            treeSelect.setId(idFunc.apply(item));
            treeSelect.setParentId(parentIdFunc.apply(item));
            treeSelect.setLabel(labelFunc.apply(item));
            return treeSelect;
        }).collect(Collectors.toList());

        Map<Long, TreeSelect> map = all.stream().collect(Collectors.toMap(TreeSelect::getId, t -> t));

        List<TreeSelect> returnList = new ArrayList<>();
        for (TreeSelect item : all) {
            if (item.getParentId() == 0) {
                returnList.add(item);
                continue;
            }
            TreeSelect parent = map.get(item.getParentId());
            if (parent != null) {
                List<TreeSelect> children = parent.getChildren();
                if (children == null) {
                    children = new ArrayList<>();
                    parent.setChildren(children);
                }
                children.add(item);
            }
        }
        return returnList;
    }


    public static <T> List<TreeSelect> buildSiteTreeSelect(List<T> list,
                                                       Function<T, Long> idFunc,
                                                       Function<T, String> labelFunc,
                                                       Function<T, Long> parentIdFunc,
                                                           Function<T, Integer> siteFunc
    ) {

        List<TreeSelect> all = list.stream().map(item -> {
            TreeSelect treeSelect = new TreeSelect();
            treeSelect.setId(idFunc.apply(item));
            treeSelect.setParentId(parentIdFunc.apply(item));
            treeSelect.setLabel(labelFunc.apply(item));
            treeSelect.setSite(siteFunc.apply(item));
            //treeSelect.setDisabled(siteFunc.apply(item) == 0);
            return treeSelect;
        }).collect(Collectors.toList());

        Map<Long, TreeSelect> map = all.stream().collect(Collectors.toMap(TreeSelect::getId, t -> t));

        List<TreeSelect> returnList = new ArrayList<>();
        for (TreeSelect item : all) {
            if (item.getParentId() == 0) {
                returnList.add(item);
                continue;
            }
            TreeSelect parent = map.get(item.getParentId());
            if (parent != null) {
                List<TreeSelect> children = parent.getChildren();
                if (children == null) {
                    children = new ArrayList<>();
                    parent.setChildren(children);
                }
//                item.setDisabled(false);
                children.add(item);
            }
        }
        return returnList;
    }
    public static <T> List<TreeSelect> buildCodeTreeSelect(List<T> list,
                                                           Function<T, Long> idFunc,
                                                           Function<T, String> codeFunc,
                                                           Function<T, String> labelFunc,
                                                           Function<T, Long> parentIdFunc
    ) {

        List<TreeSelect> all = list.stream().map(item -> {
            TreeSelect treeSelect = new TreeSelect();
            treeSelect.setId(idFunc.apply(item));
            treeSelect.setCode(codeFunc.apply(item));
            treeSelect.setParentId(parentIdFunc.apply(item));
            treeSelect.setLabel(labelFunc.apply(item));
            return treeSelect;
        }).collect(Collectors.toList());

        Map<Long, TreeSelect> map = all.stream().collect(Collectors.toMap(TreeSelect::getId, t -> t));

        List<TreeSelect> returnList = new ArrayList<>();
        for (TreeSelect item : all) {
            if (item.getParentId() == 0) {
                returnList.add(item);
                continue;
            }
            TreeSelect parent = map.get(item.getParentId());
            if (parent != null) {
                List<TreeSelect> children = parent.getChildren();
                if (children == null) {
                    children = new ArrayList<>();
                    parent.setChildren(children);
                }
//                item.setDisabled(false);
                children.add(item);
            }
        }
        return returnList;
    }
}
